package com.itheima.aop;

import com.itheima.mapper.EmpLoginLogMapper;
import com.itheima.pojo.Emp;
import com.itheima.pojo.EmpLoginLog;
import com.itheima.pojo.LoginInfo;
import com.itheima.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Slf4j
@Aspect
@Component
public class LoginLogAspect {
    
    @Autowired
    private EmpLoginLogMapper empLoginLogMapper;

    //切入点是LoginController.login方法
    @Around("execution(* com.itheima.controller.LoginController.login(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        //joinPoint切入点信息 public Result login(@RequestBody Emp emp)
        long start = System.currentTimeMillis();
        log.info("LoginLogAspect -> around ...");
        EmpLoginLog empLoginLog = new EmpLoginLog();
        empLoginLog.setLoginTime(LocalDateTime.now());

        //执行原始方法
        Object result = null;
        try {
            //设置登录用户的信息(username,password)
            setLoginUserInfo(empLoginLog, joinPoint);
            result = joinPoint.proceed();
            //一定成功了吗?
            //Result(code=1)，解析登录的结果，才知道是否成功
            setJwt(empLoginLog, result);
        } catch (Throwable e) {
            empLoginLog.setIsSuccess((short)0);
            throw e;
        } finally {
            empLoginLog.setCostTime(System.currentTimeMillis() - start);
            empLoginLogMapper.insert(empLoginLog);
        }
        log.info("LoginLogAspect -> around ...");
        return result;
    }

    // 给log对象设置JWT令牌，只有成功才有令牌
    // 参数2 result 为原始方法返回值 Result,
    private void setJwt(EmpLoginLog empLoginLog, Object result) {
        if(result instanceof Result){
            Result r = (Result)result;
            if(r.getCode() == 1){//成功
                empLoginLog.setIsSuccess((short)1);
                //获取JWT令牌
                //获取登录成功时设置data对象, LoginInfo
                LoginInfo loginInfo = (LoginInfo)r.getData();
                empLoginLog.setJwt(loginInfo.getToken());
            }else{
                empLoginLog.setIsSuccess((short)0);
            }
        }
    }

    //给log对象设置username与password
    private void setLoginUserInfo(EmpLoginLog empLoginLog, ProceedingJoinPoint joinPoint) {
        //如何获取请求参数
        //public Result login(@RequestBody Emp emp)
        Object args = joinPoint.getArgs()[0];//参数只有一个，所以直接使用索引0
        //类型强制转换
        Emp emp = (Emp)args;
        empLoginLog.setUsername(emp.getUsername());
        empLoginLog.setPassword(emp.getPassword());
    }
}
